上篇文章总结了下关于HTML的语义化,以及我在学习语义化标签后,对语义化标签使用的看法。这篇主要写我觉的比较重要的语义标签使用场景以及使用。

与C#这样严格的编程语言相比,HTML中语义标签的使用更接近我们平常说话用的自然语言。我们平时说话并没有唯一的标准措辞,语义标签的使用也是一样。下面写几个我觉得比较重要的语义标签使用场景。

作为自然语言延伸的语义类标签

语义这个词从定义上就是文科的,因此语义问题是个文科问题,所以我们这里讲语义标签的使用的第一个场景,也是最自然的使用场景,就是:作为自然语言和纯文本的补充,用来表达一定的结构或者消除歧义。

先举个例子:

如图,在【犀利】的上方可以加上标注,但是这种操作如果使用H5以前的内容来做的话,花费精力还是能够实现的。但是在HTML5中,就引入了这个表示ruby的标签,它由ruby、rt、rp三个标签来实现。

所以说,这些情况里存在的语义,其实原本就存在了,只是我们用纯文字是没法表达的,HTML作为一种“超文本”语言,支持这些文字表达就是必要的了。

避免歧义

除了上述所说的作为自然语言延伸到语义类标签出现以外,还有一种情况是,HTML的有些标签实际上就是必要的,甚至必要的程度可以达到:如果没有这个标签,文字会产生歧义的程度。

这里介绍 em 标签

例如下面这句话:

1
今天我吃了一个苹果

看上去它很清楚,但是实际上,这句话放到不同上下文中,可能表达完全不同的意思。

1
2
昨天我吃了一个香蕉。
今天我吃了一个苹果。

再比如:

1
2
昨天我吃了两个苹果。
今天我吃了一个苹果。

试着读一读,这两段里面的“今天我吃了一个苹果”,你是不是发现读音不自觉地发生了变化?

实际上,不仅仅是读音,这里的意思也发生了变化。前一段中,表示我今天吃的是苹果,而不是别的什么东西,后一段中,则表示我今天只吃了一个苹果,没有多吃。

当没有上下文时,如何消除歧义呢?这就要用到em标签了。em表示重音:

1
2
今天我吃了一个<em>苹果</em>
今天我吃了<em>一个</em>苹果。

通过em标签,我们可以消除这样的歧义。

一些文章常常会拿em和strong做对比,实际上,只要理解了em的真正意思,它和strong可谓天差地别,并没有任何混淆的可能。

作为标题摘要的语义类标签

介绍完自然语言的语义场景后,另一个语义重要使用场景,就是文章的结构。中国古代小说就形成了“章-回”的概念,西方的戏剧也有幕的区分,所以人类的自然语言作品也是如出一辙。

HTML也应该支持这样的需求。HTML语义标签中,有不少是用于支持这样的结构的标签。

语义化的HTML能够支持自动生成目录结构,HTML标准中还专门规定了生成目录结构的算法,即使我们并不打算深入实践语义,也应该尽量在大的层面上保证这些元素的语义化使用。

从HTML 5开始,就有了section标签,这个标签可不仅仅是一个“有语义的div”,它会改变h1-h6的语义。section的嵌套会使得其中的h1-h6下降一级,因此,在HTML5以后,只需要section和h1就足以形成文档的树形结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
<section>
<h1>HTML语义</h1>
<p>balah balah balah balah</p>
<section>
<h1>弱语义</h1>
<p>balah balah</p>
</section>
<section>
<h1>结构性元素</h1>
<p>balah balah</p>
</section>
......
</section>

这段代码同样会形成前面例子的标题结构:

  • HTML语义
    • 弱语义
    • 结构性元素
    • ……

作为整体结构的语义类标签

最后一个场景,随着越来越多的浏览器推出“阅读模式”,以及各种非浏览器终端的出现,语义化的HTML适合机器阅读的特性变得越来越重要。

应用了语义化结构的页面,可以明确地提示出页面信息的主次关系,它能让浏览器很好地支持“阅读视图功能”,还可以让搜索引擎的命中率提升,同时,它也对视障用户的读屏软件更友好。(如果一个页面只有 span 和 div,视障软件如果把这个网页读给用户? 读 “ div 开始 class=”tile” 今天天气很好 div 结束” 还是读 “标题:今天天气很好” 那个方式更好呢?)

正确使用整体结构类的语义标签,可以让页面对机器更友好。比如,这里一个典型的body类似这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>
<header>
<nav>
……
</nav>
</header>
<aside>
<nav>
……
</nav>
</aside>
<section>……</section>
<section>……</section>
<section>……</section>
<footer>
<address>……</address>
</footer>
</body>

在body下面,有一个header,header里面是一个nav,跟header同级的有一个aside,aside里面也有一个nav。接下来是文章的整体,也就是一个一个的section。section里面可能还有嵌套,但是我们就不管了,最后是一个footer,这个footer里面可能有address这样的内容。

除此之外,还有article,article是一种特别的结构,它表示具有一定独立性质的文章。所以,article和body具有相似的结构,同时,一个HTML页面中,可能有多个article存在。

一个典型的场景是多篇新闻展示在同一个新闻专题页面中,这种类似报纸的多文章结构适合用article来组织。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>
<header>……</header>
<article>
<header>……</header>
<section>……</section>
<section>……</section>
<section>……</section>
<footer>……</footer>
</article>
<article>
……
</article>
<article>
……
</article>
<footer>
<address></address>
</footer>
</body>

body里面有自己的header和footer,然后里面是竖篇的article,每一个article里面都有自己的header、section、footer。这是一个典型的多文章结构。

在这个结构里,我们看到了一些新标签,逐个介绍一下。

  • header,如其名,通常出现在前部,表示导航或者介绍性的内容。
  • footer,通常出现在尾部,包含一些作者信息、相关链接、版权信息等。

header和footer一般都是放在article或者body的直接子元素,但是标准中并没有明确规定,footer也可以和aside,nav,section相关联(header不存在关联问题)。

  • aside,表示跟文章主体不那么相关的部分,它可能包含导航、广告等工具性质的内容。

aside很容易被理解为侧边栏,实际上二者是包含关系,侧边栏是aside,aside不一定是侧边栏。

aside和header中都可能出现导航(nav标签),二者的区别是,header中的导航多数是到文章自己的目录,而aside中的导航多数是到关联页面或者是整站地图。

最后footer中包含address,这是个非常容易被误用的标签。address并非像date一样,表示一个给机器阅读的地址,而是表示“文章(作者)的联系方式”,address明确地只关联到article和body。

总结

根据本篇和上篇文章,介绍了一些基本原则和HTML文档的整体结构,从整体上了解了HTML语义。因此在回答是否要语义化的问题时:我们应该分开一些场景来看语义,把它用在合适的场景下,可以获得额外的效果。

回顾一下本篇的三个明确的场景:

  • 自然语言表达能力的补充;
  • 文章标题摘要;
  • 适合机器阅读的整体结构。